<?php

namespace app\beautiful\logic\order;

use app\beautiful\logic\FreightLogic;

use app\beautiful\model\mall\GoodsModel;

use app\beautiful\model\mall\GoodsSkuModel;

use app\beautiful\model\member\MemberCouponModel;

use app\beautiful\model\order\GoodsOrderItemModel;

use app\beautiful\model\order\GoodsOrderModel;

use app\beautiful\model\setting\SettingBalanceModel;

use app\beautiful\model\setting\SettingIntegralModel;



class OrderPreSaleLogic{

    use OrderTrait;

    protected $goods_data=[];

    protected $total_price=0;

    protected $member_coupon_id;

    protected $sku_datas=[];

    protected $order_item_data=[];

    protected $num;



    public function createOrder($params)

    {



        //判断用户

        empty($params['member_id']) && $this->error('请先登录后再操作');

        $this->checkMember($params['member_id'], false);



        //判断商品

        if(empty($params['goods']) || !is_array($params))  $this->error('请选择商品');

        foreach ($params['goods'] as $k => $v){

            $this->checkGoods($v,false);

        }





        //判断配送方式

        if( empty($params['logistics_type']) || !in_array($params['logistics_type'],[1,2])) $this->error('请选择配送方式');

        //快速配送判断邮寄地址

        if($params['logistics_type']==1){

            empty($params['receiving_name']) && $this->error('请输入收货人');

            if(empty($params['receiving_mobile']) || (!is_mobile($params['receiving_mobile']) && !is_phone($params['receiving_mobile'])) )  $this->error('请输入收货人手机号');

            empty($params['receiving_address_province']) && $this->error('请输入收货省份');

            empty($params['receiving_address_city']) && $this->error('请输入收货城市');

            empty($params['receiving_address_county']) && $this->error('请输入收货城镇');

            empty($params['receiving_address_info']) && $this->error('请输入收货具体地址');

        }



        //判断总价

        if(empty($params['total_price'])) $this->error('参数错误#1');

        if((float)$params['total_price'] != $this->total_price) $this->error('参数错误#2');



        //判断优惠卷

        $coupon_id = $params['coupon_id'] ?? 0;

        $couponBalance = 0;

        if(!empty($coupon_id)){

            if(null === $myCoupon =  MemberCouponModel::find($coupon_id)) $this->error('优惠券不存在');

            if($myCoupon->status == 1 || $myCoupon->money_limit > $this->total_price) $this->error('该优惠券不可用');

            if($myCoupon->member_id != $params['member_id'])  $this->error('该优惠券不可用');

            $couponBalance = $myCoupon->coupon_money;

        }



        //判断积分抵扣

        $use_integral=(int)$params['use_integral'];

        if($use_integral==1){

            $integral_balance=$this->getIntegralBalance($this->total_price);

        }

        $integral=isset($integral_balance) ? $integral_balance['integral'] : 0;

        $balance=isset($integral_balance) ? $integral_balance['balance'] : 0;





        //获取邮费

        $freight = 0;

        if($params['logistics_type']==1){

            $province= empty($params['receiving_address_province']) ? '' : $params['receiving_address_province'];

            $freight_logic= new FreightLogic($this->shopId);

            $freight=$freight_logic->getFreightPrice($province,$this->num);

            if($freight==-1) $this->error('收货地址暂不支持发货');

        }



        //获取需要支付的金额

        $need_pay=round((($this->total_price)*100 + $freight*100 - $couponBalance*100 - $balance*100)/100,2);



        //保存订单

        $order = new GoodsOrderModel();

        $order_data=[

            'shop_id'=>$this->shopId,

            'order_type'=>'pre_sale',

            'logistics_type'=>$params['logistics_type'],

            'member_id'=>$params['member_id'],

            'total_price'=>$this->total_price,

            'need_pay'=>$need_pay,

            'freight'=>$freight,

            'member_coupon_id'=>$params['coupon_id'],

            'coupon_money'=>$couponBalance,

            'use_integral'=>isset($integral_balance) ? $integral_balance['integral'] : 0,

            'integral_balance'=>isset($integral_balance) ? $integral_balance['balance'] : 0,

            'is_paid'=>0,

            'status'=>1,

            'from_type'=>$params['from_type']

        ];

        if($params['logistics_type']==1){

            $order_data['receiving_name']=$params['receiving_name'];

            $order_data['receiving_mobile']=$params['receiving_mobile'];

            $order_data['receiving_address_province']=$params['receiving_address_province'];

            $order_data['receiving_address_city']=$params['receiving_address_city'];

            $order_data['receiving_address_county']=$params['receiving_address_county'];

            $order_data['receiving_address_info']=$params['receiving_address_info'];

        }

        $order->save($order_data);



        //保存订单商品

        foreach ($this->order_item_data as $k => $v){

            $this->order_item_data[$k]['order_id']=$order->order_id;

        }

        $order_item_model= new GoodsOrderItemModel();

        $order_item_model->saveAll($this->order_item_data);



        //保存商品

        $goods_model=new GoodsModel();

        $goods_model->saveAll($this->goods_data);



        //保存商品规格

        $goods_sku_model = new GoodsSkuModel();

        $goods_sku_model->saveAll($this->sku_datas);



        return $order->order_id;

    }



    public function cancelOrder($params)

    {

        $this->checkMember($params['member_id'],false);

        $this->checkOrder($params['order_id'],true);



        if($this->order->order_type != 'pre_sale') $this->error('订单不存在');

        if($this->order->is_delete != 0) $this->error('订单不存在');

        if($this->order->is_paid == 1 || $this->order->status != 1) $this->error('订单无法取消');



        $this->order->status=-1;

        $this->order->save();



        $this->cancelGoods();



        //保存商品

        $goods_model=new GoodsModel();

        $goods_model->saveAll($this->goods_data);



        //保存商品规格

        $goods_sku_model = new GoodsSkuModel();

        $goods_sku_model->saveAll($this->sku_datas);



        return true;

    }



    public function createFakeOrder($params)

    {

        //判断用户

        empty($params['member_id']) && $this->error('请先登录后再操作');

        $this->checkMember($params['member_id'], false);



        //判断商品

        if(empty($params['goods']) || !is_array($params))  $this->error('请选择商品');

        foreach ($params['goods'] as $k => $v){

            $this->checkGoods($v,false);

        }





        //判断配送方式

        if( empty($params['logistics_type']) || !in_array($params['logistics_type'],[1,2])) $this->error('请选择配送方式');

        //快速配送判断邮寄地址

        if($params['logistics_type']==1){

            empty($params['receiving_name']) && $this->error('请输入收货人');

            if(empty($params['receiving_mobile']) || (!is_mobile($params['receiving_mobile']) && !is_phone($params['receiving_mobile'])) )  $this->error('请输入收货人手机号');

            empty($params['receiving_address_province']) && $this->error('请输入收货省份');

            empty($params['receiving_address_city']) && $this->error('请输入收货城市');

            empty($params['receiving_address_county']) && $this->error('请输入收货城镇');

            empty($params['receiving_address_info']) && $this->error('请输入收货具体地址');

        }



        //判断总价

        if(empty($params['total_price'])) $this->error('参数错误#1');

        if((float)$params['total_price'] != $this->total_price) $this->error('参数错误#2');





        //获取邮费

        $freight = 0;

        if($params['logistics_type']==1){

            $province= empty($params['receiving_address_province']) ? '' : $params['receiving_address_province'];

            $freight_logic= new FreightLogic($this->shopId);

            $freight=$freight_logic->getFreightPrice($province,$this->num);

            if($freight==-1) $this->error('收货地址暂不支持发货');

        }



        //获取需要支付的金额

        $need_pay=$params['need_pay'];





        //保存订单

        $order = new GoodsOrderModel();

        $order_data=[

            'shop_id'=>$this->shopId,

            'order_type'=>'pre_sale',

            'logistics_type'=>$params['logistics_type'],

            'member_id'=>$params['member_id'],

            'total_price'=>$this->total_price,

            'need_pay'=>$need_pay,

            'freight'=>$freight,

            'is_paid'=>1,

            'pay_time'=>time(),

            'pay_type'=>'offline',

            'status'=>$params['status'],

        ];

        if($params['logistics_type']==1){

            $order_data['receiving_name']=$params['receiving_name'];

            $order_data['receiving_mobile']=$params['receiving_mobile'];

            $order_data['receiving_address_province']=$params['receiving_address_province'];

            $order_data['receiving_address_city']=$params['receiving_address_city'];

            $order_data['receiving_address_county']=$params['receiving_address_county'];

            $order_data['receiving_address_info']=$params['receiving_address_info'];

        }



        $youhui_balance=round((($this->total_price)*100 + $freight*100 - $need_pay*100) /100,2);

        if($youhui_balance>0){

            $order_data['youhui_balance']=$youhui_balance;

        }

        $order->save($order_data);



        //保存订单商品

        foreach ($this->order_item_data as $k => $v){

            $this->order_item_data[$k]['order_id']=$order->order_id;

        }

        $order_item_model= new GoodsOrderItemModel();

        $order_item_model->saveAll($this->order_item_data);



        //保存商品

        $goods_model=new GoodsModel();

        $goods_model->saveAll($this->goods_data);



        //保存商品规格

        $goods_sku_model = new GoodsSkuModel();

        $goods_sku_model->saveAll($this->sku_datas);



        return $order->order_id;

    }



    public function getIntegralBalance($total_price)

    {

        $SettingBalance = SettingBalanceModel::where([['shop_id','=', $this->shopId]])->find();

        if(null === $SettingBalance){

            $integral_deduction_balance_limit_rate = 0;

        }else{

            $integral_deduction_balance_limit_rate = $SettingBalance->integral_deduction_balance_limit_rate; //积分抵扣的比率 百分比

        }

        $integralSetting = SettingIntegralModel::where([['shop_id','=', $this->shopId]])->find();

        if($integralSetting === null){ //如果是空 代表不使用积分抵扣余额

            $integral_exchange_balance = 0;

        }else{

            $integral_exchange_balance = $integralSetting->integral_exchange_balance;//汇率

        }



        $pre_can_exchange_balance=round(($total_price*($integral_deduction_balance_limit_rate*100))/10000,2);

        $pre_can_exchange_integral=$integral_exchange_balance==0 ? 0 : round(($pre_can_exchange_balance*10000)/($integral_exchange_balance*100),0);

        $member_integral=$this->member->integral;

        if($member_integral>=$pre_can_exchange_integral){

            $return=[

                'integral'=>$pre_can_exchange_integral,

                'balance'=>$pre_can_exchange_balance

            ];

        }else{

            $return=[

                'integral'=>$member_integral,

                'balance'=>round(($member_integral*($integral_exchange_balance*100))/10000,2),

            ];

        }

        return $return;



    }



    public function checkGoods($datas,$lock)

    {

        empty($datas['goods_id']) && $this->error('参数错误#3');

        empty($datas['num']) && $this->error('参数错误#4');

        $this->num = ($this->num ?? 0) + $datas['num'];



        $goods=GoodsModel::where([

            ['shop_id','=',$this->shopId],

            ['status','=',1],

            ['is_delete','=',0],

            ['goods_id','=',$datas['goods_id']],

            ['quota','>',$datas['num']]

        ])->field('goods_id,name,cover_img,original_price,yu_price,gross,quota,take_count,fictitious_take_count,is_have_sku,yu_days')

            ->lock($lock)->find();

        empty($goods) && $this->error('请选择商品');



       $sku_id=isset($datas['sku_id']) ? $datas['sku_id'] : 0;

       if($sku_id != 0){

           $sku=GoodsSkuModel::where([

               ['shop_id','=',$this->shopId],

               ['is_delete','=',0],

               ['goods_id','=',$datas['goods_id']],

               ['sku_id','=',$sku_id],

               ['quota','>',$datas['num']]

           ])->field('sku_id,name,original_price,yu_price,quota,take_count')

               ->lock($lock)->find();

           if(null === $sku) $this->error($goods->name.'的规格缺货');



       }



        //处理订单商品表

        $this->order_item_data[]=[

            'shop_id'=>$this->shopId,

            'goods_id'=>$datas['goods_id'],

            'goods_type'=>'pre_sale',

            'goods_name'=>$goods->name,

            'goods_cover_img'=>$goods->cover_img,

            'goods_sku_id'=>$sku_id,

            'goods_sku_name'=>isset($sku) ? $sku->name : '',

            'goods_original_price'=>isset($sku) ? $sku->original_price : $goods->original_price,

            'goods_price'=>isset($sku) ? $sku->yu_price : $goods->yu_price,

            'yu_days'=>$goods->yu_days,

            'goods_gross'=>$goods->gross,

            'goods_num'=>$datas['num'],

        ];



        $price=isset($sku) ? $sku->yu_price :  $goods->yu_price;

        $this->total_price=round((($this->total_price)*100+$price*$datas['num']*100)/100,2);



       //处理商品表

        $goods=$goods->toArray();

        $goods['quota']=$goods['quota']-$datas['num'];

        $goods['take_count']=$goods['take_count']+$datas['num'];

        $goods['fictitious_take_count']=$goods['fictitious_take_count']+$datas['num'];

        $this->goods_data[]=$goods;



       //处理规格表

        if(isset($sku)){

            $sku=$sku->toArray();

            $sku['quota']=$sku['quota']-$datas['num'];

            $sku['take_count']=$sku['take_count']+$datas['num'];

            $this->sku_datas[]=$sku;

        }



    }



    protected function cancelGoods()

    {

        $order_item_data=GoodsOrderItemModel::where([

            ['shop_id','=',$this->shopId],

            ['order_id','=',$this->order->order_id],

            ['goods_type','=','pre_sale']

        ])->field('goods_id,goods_sku_id,goods_num')->select()->toArray();

        $goods_ids=[];$sku_ids=[];$order_item_array=[];



        if(!empty($order_item_data)){

            foreach ($order_item_data as $k => $v){

                $goods_ids[]=$v['goods_id'];

                $sku_ids[]=$v['goods_sku_id'];

                $order_item_array['goods'][$v['goods_id']]=$v;

                $order_item_array['sku'][$v['goods_sku_id']]=$v;

            }

        }



        //处理商品

        $goods_data=GoodsModel::where([

            ['shop_id','=',$this->shopId],

            ['goods_id','in',$goods_ids]

        ])->field('goods_id,quota,take_count,fictitious_take_count')->select()->toArray();



        foreach ($goods_data as $k => $v){

            $num=$order_item_array['goods'][$v['goods_id']]['goods_num'] ?? 0;

            $goods_data[$k]['quota']=$v['quota'] +$num;

            $goods_data[$k]['fictitious_take_count']=($v['fictitious_take_count'] -$num) <=0 ? $v['fictitious_take_count'] : ($v['fictitious_take_count'] -$num);

            $goods_data[$k]['take_count']=$v['take_count'] -$num;

        }

        $this->goods_data=$goods_data;



        //处理规格

        $sku_datas=GoodsSkuModel::where([

            ['shop_id','=',$this->shopId],

            ['sku_id','in',$sku_ids],

        ])->field('sku_id,quota,take_count')->select()->toArray();



        foreach ($sku_datas as $k => $v){

            $num=$order_item_array['sku'][$v['sku_id']]['goods_num'] ?? 0;

            $sku_datas[$k]['quota']=$v['quota'] +$num;

            $sku_datas[$k]['take_count']=$v['take_count'] -$num;

        }

        $this->sku_datas=$sku_datas;







    }

}